﻿using System;
using System.Collections.Generic;
using System.Linq;
using Onshi.POS.Modelo.Entidades;
using Onshi.POS.Modelo.Enumeradores;
using Onshi.POS.Modelo.Objetos;
using Onshi.POS.Repositorios;
using Onshi.POS.Usuarios.Vistas;

namespace Onshi.POS.Usuarios
{
    public class UsuariosAltaBajaModificacionHabilitacionPresentador
    {
        #region Constructores

        public UsuariosAltaBajaModificacionHabilitacionPresentador(IUsuariosAltaBajaModificacionHabilitacion vista)
        {
            this.vista = vista;
        }

        #endregion

        #region Atributos

        private IUsuariosAltaBajaModificacionHabilitacion vista;
        private List<Usuario> lista;

        #endregion

        #region Propiedades

        private RepositorioUsuario RepositorioUsuario
        {
            get { return new RepositorioUsuario(); }
        }

        private RepositorioRegistro RepositorioRegistro
        {
            get { return new RepositorioRegistro(); }
        }

        private RepositorioTipoRegistro RepositorioTipoRegistro
        {
            get { return new RepositorioTipoRegistro(); }
        }

        private RepositorioPerfil RepositorioPerfil
        {
            get { return new RepositorioPerfil(); }
        }

        #endregion

        #region Metodos

        private void ActualizarLista()
        {
            lista = RepositorioUsuario.DevolverTodos();
        }

        private List<Usuario> FiltrarLista()
        {
            if (lista != null)
            {
                var consulta = (from item in lista
                                where item.Nombre.Trim().ToLower().Contains(vista.NombreFiltro.Trim().ToLower())
                                & (item.TieneObservacion == (vista.TieneObservacionFiltro == EnumEstadoCheck.TODOS ? item.TieneObservacion : (vista.TieneObservacionFiltro == EnumEstadoCheck.SI ? true : false)))
                                & (item.EstaEliminado == (vista.EstaEliminadoFiltro == EnumEstadoCheck.TODOS ? item.EstaEliminado : (vista.EstaEliminadoFiltro == EnumEstadoCheck.SI ? true : false)))
                                & (item.Perfil.Id == (vista.IdPerfilFiltro == (Int32)EnumPerfil.TODOS ? item.Perfil.Id : vista.IdPerfilFiltro))
                                select item).ToList();
                return consulta;
            }
            else
                return lista;
        }

        public void Inicializar()
        {
            ActualizarLista();
            vista.Lista = lista;
        }

        public void Aceptar()
        {
            switch (vista.EstadoABM)
            {
                case EnumEstadoAltaBajaModificacionHabilitacion.ALTA:
                    if (!DatosComunes.TienePermiso(EnumPermiso.USUARIO_ALTA))
                        throw new Exception(DatosComunes.SinPermiso);
                    break;
                case EnumEstadoAltaBajaModificacionHabilitacion.MODIFICACION:
                    if (!DatosComunes.TienePermiso(EnumPermiso.USUARIO_MODIFICACION))
                        throw new Exception(DatosComunes.SinPermiso);
                    break;
            }
            if (vista.EstadoABM == EnumEstadoAltaBajaModificacionHabilitacion.MODIFICACION)
            {
                if (vista.IdUsuario == (Int32)EnumUsuario.ADMINISTRADOR)
                    throw new Exception("El usuario no se puede modificar");
                if (RepositorioUsuario.DevolverPorId(vista.IdUsuario) == null)
                    throw new Exception("El usuario no existe");
            }
            var usuario = new Usuario();
            usuario.Perfil = RepositorioPerfil.DevolverPorId(vista.IdPerfil);
            if (usuario.Perfil == null)
                throw new Exception("El perfil no existe");
            usuario.Nombre = vista.Nombre.Trim();
            if (usuario.Nombre == String.Empty)
                throw new Exception("El nombre no puede quedar vacio");
            if (vista.Clave.Trim() == String.Empty)
                throw new Exception("La contraseña no puede quedar vacia");
            usuario.Clave = Encriptacion.SHA1(vista.Clave.Trim());
            usuario.Observacion = vista.Observacion.Trim();
            var usuarioExistente = RepositorioUsuario.DevolverPorNombre(usuario.Nombre);
            var registro = new Registro();
            registro.Usuario = DatosComunes.Usuario;
            switch (vista.EstadoABM)
            {
                case EnumEstadoAltaBajaModificacionHabilitacion.ALTA:
                    registro.Tipo = RepositorioTipoRegistro.DevolverPorId((Byte)EnumTipoRegistro.USUARIO_ALTA);
                    break;
                case EnumEstadoAltaBajaModificacionHabilitacion.MODIFICACION:
                    registro.Tipo = RepositorioTipoRegistro.DevolverPorId((Byte)EnumTipoRegistro.USUARIO_MODIFICACION);
                    break;
            }
            if (registro.Tipo == null)
                throw new Exception("El tipo de registro no existe");
            switch (vista.EstadoABM)
            {
                case EnumEstadoAltaBajaModificacionHabilitacion.ALTA:
                    if (usuarioExistente != null)
                        throw new Exception("Ya existe un usuario con ese nombre");
                    RepositorioUsuario.Insertar(usuario);
                    break;
                case EnumEstadoAltaBajaModificacionHabilitacion.MODIFICACION:
                    usuario.Id = vista.IdUsuario;
                    if (usuarioExistente != null && usuarioExistente.Id != usuario.Id)
                        throw new Exception("Ya existe un usuario con ese nombre");
                    RepositorioUsuario.Modificar(usuario);
                    break;
            }
            RepositorioRegistro.Insertar(registro, usuario);
            ActualizarLista();
            vista.Lista = FiltrarLista();
        }

        public void Eliminar()
        {
            if (!DatosComunes.TienePermiso(EnumPermiso.USUARIO_BAJA))
                throw new Exception(DatosComunes.SinPermiso);
            if (vista.IdUsuario == (Int32)EnumUsuario.ADMINISTRADOR)
                throw new Exception("El usuario no se puede eliminar");
            var usuario = RepositorioUsuario.DevolverPorId(vista.IdUsuario);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (usuario.EstaEliminado)
                throw new Exception("El usuario no se encuentra habilitado");
            var registro = new Registro();
            registro.Usuario = DatosComunes.Usuario;
            registro.Tipo = RepositorioTipoRegistro.DevolverPorId((Byte)EnumTipoRegistro.USUARIO_BAJA);
            if (registro.Tipo == null)
                throw new Exception("El tipo de registro no existe");
            RepositorioUsuario.Eliminar(usuario);
            RepositorioRegistro.Insertar(registro, usuario);
            ActualizarLista();
            vista.Lista = FiltrarLista();
        }

        public void Habilitar()
        {
            if (!DatosComunes.TienePermiso(EnumPermiso.USUARIO_HABILITACION))
                throw new Exception(DatosComunes.SinPermiso);
            if (vista.IdUsuario == (Int32)EnumUsuario.ADMINISTRADOR)
                throw new Exception("El usuario no se puede habilitar");
            var usuario = RepositorioUsuario.DevolverPorId(vista.IdUsuario);
            if (usuario == null)
                throw new Exception("El usuario no existe");
            if (!usuario.EstaEliminado)
                throw new Exception("El usuario no se encuentra eliminado");
            var registro = new Registro();
            registro.Usuario = DatosComunes.Usuario;
            registro.Tipo = RepositorioTipoRegistro.DevolverPorId((Byte)EnumTipoRegistro.USUARIO_HABILITACION);
            if (registro.Tipo == null)
                throw new Exception("El tipo de registro no existe");
            RepositorioUsuario.Eliminar(usuario);
            RepositorioRegistro.Insertar(registro, usuario);
            ActualizarLista();
            vista.Lista = FiltrarLista();
        }

        public void Actualizar()
        {
            ActualizarLista();
            vista.Lista = FiltrarLista();
        }

        public void Filtrar()
        {
            vista.Lista = FiltrarLista();
        }

        public void Imprimir()
        {
            vista.ListaReporte = FiltrarLista();
        }

        #endregion
    }
}
